# 我们把变量从内存中变成可存储或传输的过程称之为序列化，在Python中叫pickling，
# 在其他语言中也被称之为serialization，marshalling，flattening等等，都是一个意思。
# 反过来，把变量内容从序列化的对象重新读到内存里称之为反序列化，即unpickling。
# Python提供了pickle模块来实现序列化。
import pickle, json

dict = {'name': 'kun', 'sex': 'femal'}
d = pickle.dumps(dict)
print(d)
# pickle.dumps()方法把任意对象序列化成一个bytes，然后，就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object：
path = 'F:/pycharm_demo/pycharm_one/leanr_base/IO编程_08/pickle.txt'
f = open(path, 'wb')
pickle.dump(d, f)
f.close()
# 当我们要把对象从磁盘读到内存时，可以先把内容读到一个bytes，然后用pickle.loads()方法反序列化出对象，也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象
ff = open(path, 'rb')
dd = pickle.load(ff)
ff.close()
print(dd)
print('*************************JOSN***************************************')
# 序列化为JSON，因为JSON表示出来就是一个字符串，可以被所有语言读取，
# 也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式，并且比XML更快，而且可以直接在Web页面中读取
# JSON表示的对象就是标准的JavaScript语言的对象，JSON和Python内置的数据类型对应如下：JSON标准规定JSON编码是UTF-8
# JSON类型	            Python类型
# {}	                dict
# []	                list
# "string"	            str
# 1234.56	            int或float
# true/false	        True/False
# null	                None
jsonDate = json.dumps(dict)  # dumps()方法返回一个str，内容就是标准的JSON
print(jsonDate)
# 要把JSON反序列化为Python对象，用loads()或者对应的load()方法，前者把JSON的字符串反序列化，后者从file-like Object中读取字符串并反序列化：
print(json.loads(jsonDate))
print('*************************JOSN高阶***************************************')


# 用class表示对象，然后序列化，转成josn
# 可选参数default就是把任意一个对象变成一个可序列为JSON的对象，我们只需要为Student专门写一个转换函数，再把函数传进去即可：
class Student(object):
    def __init__(self, name, age, city) -> None:
        self.name = name
        self.age = age
        self.city = city


def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'city': std.city
    }


stu = Student('liangkun', 29, 'wuhan')
print(json.dumps(stu, default=student2dict))
# 所有类通用：---- 把任意class的实例变为dict：
# 因为通常class的实例都有一个__dict__属性，它就是一个dict，用来存储实例变量。也有少数例外
print(json.dumps(stu, default=lambda obj: obj.__dict__))


# 果我们要把JSON反序列化为一个Student对象实例，loads()方法首先转换出一个dict对象，然后，我们传入的object_hook函数负责把dict转换为Student实例：
def dict2student(d):
    return Student(d['name'], d['age'], d['city'])


jsonstr = '{"name":"likui", "age": "90", "city": "beijing"}'
print(json.loads(jsonstr, object_hook=dict2student))
# 对中文进行JSON序列化时，json.dumps()提供了一个ensure_ascii参数，观察该参数对结果的影响：
obj = {'name': '大明劫', 'duration': '150分钟'}
print(json.dumps(obj, ensure_ascii=False))
print(json.dumps(obj, ensure_ascii=True))


